package models

import (
	"coding.net/vco/mder/modules/coding"
	"coding.net/vco/mder/modules/log"
	"coding.net/vco/mder/modules/target"
	"coding.net/vco/mder/modules/util"
	"encoding/json"
	"fmt"
	"github.com/BurntSushi/toml"
	"github.com/Unknwon/com"
	"net/http"
	"strings"
)

/*

[sync]
# 忽略目录或文件
ignores = ["LICENSE","demo"]
[blog]
# 博客主题
theme="default"
# 博客标题
title="代码刀客"
# 博客描述
description="天下事有难易乎?为之,则难者亦易矣;不为,则易者亦难矣.人之为学有难易乎"
# 博客关键词
keywords=[]

[author]
nick="leonlau"
gravatar=""
mark="刀客男"
email="vco@coding.net"
github=""
twitter=""
# 你可以增加自定义属性
[ext]

*/

const (
	MDER_VERSION   = "0.1 beta"
	mder_name      = "mder"
	mder_dev_nick  = "leonlau"
	mder_dev_email = "leonlau@aliyun.com"
	mder_dev_url   = "https://coding.net/u/vco"
	mder_url       = "https://coding.net/u/vco/p/mder"
	mder_toml      = "/.mder.toml"
)

var mder *Mder

//mder 统一小写访问
var mderMap map[string]interface{}

func init() {
	t := target.New()
	RefreshMderToml()
	//主动同步一次
	coding.Rebuild(t.GlobalKey, t.Project, t.Ref)
}

func RefreshMderToml() {
	mder = &Mder{}
	mder.fetchToml()
	data, _ := json.Marshal(mder)
	json.Unmarshal(data, &mderMap)
}

func NewMderMap() map[string]interface{} {
	return mderMap
}

func NewMder() *Mder {
	return mder
}

type Mder struct {
	App            App                    `json:"app"`
	Author         Author                 `json:"author"`
	Blog           Blog                   `json:"blog"`
	Sync           Sync                   `json:"sync"`
	Theme          Theme                  `json:"theme"`
	Ext            map[string]interface{} `json:"ext"` //自定义
	lastCommitDate int64
}

func (this Mder) isLastest(lastCommitDate int64) bool {
	return this.lastCommitDate == lastCommitDate && lastCommitDate != 0
}

type Theme struct {
	Name      string    `json:"name"`
	Version   string    `json:"version"`
	Developer Developer `json:"developer"`
}

type App struct {
	Url       string    `json:"url"`
	Version   string    `json:"version"`
	Name      string    `json:"name"`
	Developer Developer `json:"developer"`
}

type Developer struct {
	Nick    string `json:"nick"`
	Url     string `json:"url"`
	Email   string `json:"email"`
	Company string `json:"company"`
}

type Sync struct {
	Ignores  []string `json:"ignores"`
	Interval int      `json:"interval"`
}

type Blog struct {
	Title       string   `json:"title"`
	Theme       string   `json:"theme"`
	Description string   `json:"description"`
	Keywords    []string `json:"keywords"`
}

type Author struct {
	Nick     string `json:"nick"`
	Gravatar string `json:"gravatar"`
	Mark     string `json:"mark"`
	Email    string `json:"email"`
	Github   string `json:"github"`
	Twitter  string `json:"twitter"`
	Coding   string `json:"coding"`
	Facebook string `json:"facebook"`
	Qq       string `json:"qq"`
}

//fetch

func (this *Mder) fetchToml() {
	t := target.New()
	url := util.FileBlobInfoUrl(t.GlobalKey, t.Project, t.Ref+mder_toml)
	log.Debug("", t)
	v := &coding.CodingFileResult{}
	com.HttpGetJSON(&http.Client{}, url, v)
	if v.Success() {
		if this.isLastest(v.Data.File.LastCommitDate) { //最新
			log.Debug("MderToml is lastest:%s,skip it", v.Data.File.LastCommitDate)
			return
		}
		_, err := toml.DecodeReader(strings.NewReader(v.Data.File.Data), this)
		if err != nil {
			log.Error(err.Error())
			return
		}

		this.lastCommitDate = v.Data.File.LastCommitDate
		//读取主题
		this.App = newApp()
		this.Theme = newTheme(this.Blog.Theme)

		coding.Ignores = this.Sync.Ignores
		log.Debug("", this.Sync.Ignores, coding.Ignores)
	} else {
		log.Error("远程请 API(%s) 异常", url)
	}
}

//读取主题信息
func newTheme(theme string) Theme {
	t := Theme{}
	toml.DecodeFile(fmt.Sprintf("templates/theme/%s/.theme.toml", theme), &t)
	return t
}

func newApp() App {
	return App{
		Version: MDER_VERSION,
		Name:    mder_name,
		Url:     mder_url,
		Developer: Developer{
			Nick:  mder_dev_nick,
			Email: mder_dev_email,
			Url:   mder_dev_url,
		},
	}
}
